import { defineStore } from 'pinia';
import { ref } from 'vue';

// ResourceType 用于描述 resource 对象的结构，key 为字符串，值为任意类型
interface ResourceType {
    [key: string]: any;
}

// 创建 ws 相关的 Pinia store
export const useWsStore = defineStore('ws', () => {
    // socketFlag 表示 WebSocket 是否正在连接或已连接成功
    const socketFlag = ref<boolean>(false);

    // repeatNum 表示 WebSocket 允许的最大重连次数，从环境变量读取
    const repeatNum: number = Number(import.meta.env.VITE_SOCKET_NUM);

    // heartFlag 表示心跳检测的状态，true 为心跳正常，false 为心跳异常
    const heartFlag = ref<boolean>(false);

    // resource 用于存储 WebSocket 过程中产生的各种数据，结构为 key-value
    const resource = ref<ResourceType>({});

    /**
     * 设置心跳检测状态
     * @param flag - 心跳状态，true 表示正常，false 表示异常
     */
    const setHeartFlag = (flag: boolean) => {
        heartFlag.value = flag;
    };

    /**
     * 设置 WebSocket 连接状态
     * @param flag - 连接状态，true 表示已连接，false 表示未连接
     */
    const setSocketFlag = (flag: boolean) => {
        socketFlag.value = flag;
    };

    /**
     * 设置 resource 中指定 key 的值
     * @param key - 要设置的键名
     * @param value - 要设置的值
     * @param type - 操作类型，'rewrite' 为覆盖重写，'append' 为追加（数组或对象合并）
     *
     * - rewrite: 直接覆盖原有值
     * - append: 如果原值为数组则 push，若为对象则合并，否则初始化为数组
     */
    const setResource = (
        key: string,
        value: any,
        type: 'rewrite' | 'append' = 'rewrite'
    ) => {
        if (type === 'rewrite') {
            // 覆盖原有值
            resource.value[key] = value;
        } else if (type === 'append') {
            // 若原值不存在，初始化为数组
            if (!resource.value[key]) {
                resource.value[key] = [];
            }
            // 如果原值为数组，则追加
            if (Array.isArray(resource.value[key])) {
                resource.value[key].push(value);
            } else if (
                resource.value[key] &&
                resource.value[key].constructor === Object
            ) {
                // 如果原值为对象，则合并
                resource.value[key] = {
                    ...resource.value[key],
                    ...value,
                };
            }
        }
    };

    // 返回 store 的 state 和操作方法，供组件使用
    return {
        socketFlag,
        repeatNum,
        heartFlag,
        resource,
        setHeartFlag,
        setSocketFlag,
        setResource,
    };
});